package controllers.multicast;

import java.util.HashMap;
import java.util.Map.Entry;

import controllers.SensorConfigController;
import models.CNAverage;
import models.NodeConfig;
import models.UserConfig;
import play.Logger;
import play.jobs.Job;
import util.Persistence;
import ch.bfh.abcm.rems.SensorControllerFactory;
import ch.bfh.abcm.rems.gateway.GatewayMessage;
import ch.bfh.abcm.rems.interfaces.REMSMessageReceiver;
import ch.bfh.abcm.rems.konfiguration.EventMessage;
import ch.bfh.abcm.rems.konfiguration.UpdateNodeConfigMessage;
import ch.bfh.abcm.rems.konfiguration.UpdateUserConfigMessage;
import ch.bfh.abcm.rems.sensors.tinkerforge.TFSensorController;
import ch.bfh.abcm.rems.tinkerforge.TFNodeAverageMessage;

public class MessageReceiver implements REMSMessageReceiver {

    private org.apache.log4j.Logger multicastLogger = org.apache.log4j.Logger.getLogger("multicastreceiver");

    @Override
    public void receivedGateWayMessage(GatewayMessage gatewayMessage) {
        multicastLogger.debug("REMS Node Application ignores Gatewaymessages");
        Logger.debug("REMS Node Application ignores Gatewaymessages");
    }

    @Override
    public void receivedTFNodeAverageMessage(TFNodeAverageMessage nam) {
        multicastLogger.info("Receivred " + nam.toString());
        Persistence.saveCNA(new CNAverage(nam.getPlausability(), nam.getValue(), nam.getNodeIP(), nam
                .getMeasurementIP(), nam.getSensorType()));
        // new SaveJob(nam).now();
    }

    @Override
    public void receivedUpdateUserConfigMessage(UpdateUserConfigMessage updateUserConfigMessage) {
        multicastLogger.info("Received UpdateUserConfigMessage: " + updateUserConfigMessage.getPropertyMap());
        new UpdateUserconfigJob(updateUserConfigMessage.getPropertyMap()).now();
    }

    @Override
    public void receivedUpdateNodeConfigMessage(UpdateNodeConfigMessage updateNodeConfigMessage) {
        multicastLogger.info("Received UpdateNodeConfigMessage not Implemented");
    }

    @Override
    public void receivedEventMessage(EventMessage eventMessage) {
        multicastLogger.info("Received EventMessage: " + eventMessage);
        switch (eventMessage.getEventType()) {
        case START_DATAMINING:
            Logger.info("Remote Start Datamining is not implementet");
            break;
        case STOP_DATAMINING:
            Logger.info("Remote Stop Datamining is not implementet");
            break;
        case UPDATE_SENSORCONFIG:
            Logger.info("Remote Update Sensorlist is not implementet");
            break;
        case START_VALIDATION_JOB:
            Logger.error("Remote Validationjob-Start is not implementet");
            break;
        case STOP_VALIDATION_JOB:
            Logger.error("Remote Validationjob-STOP is not implementet");
            break;
        case UPDATE_NETWORK_CONFIG:
            Logger.error("Remote Update Networkconfig is not implementet");
            break;
        default:
            Logger.error("Received Unknown EventMessageType: %s", eventMessage.getEventType());
            break;
        }

    }

    private class UpdateUserconfigJob extends Job {

        private HashMap<String, String> propertyMap;

        private UpdateUserconfigJob(HashMap<String, String> map) {
            this.propertyMap = map;
        }

        @Override
        public void doJob() throws Exception {
            for (Entry<String, String> entry : propertyMap.entrySet()) {
                Logger.info("Update Userconfig: Key: %s Value: %s", entry.getKey(), entry.getValue());
                UserConfig userconfig = UserConfig.getProperty(entry.getKey());
                userconfig.setPropertyValue(entry.getValue());
                userconfig.save();
            }
        }
    }

//    private class SaveJob extends Job {
//
//        private TFNodeAverageMessage nam;
//
//        private SaveJob(TFNodeAverageMessage data) {
//            this.nam = data;
//        }
//
//        @Override
//        public void doJob() throws Exception {
//            new CNAverage(nam.getPlausability(), nam.getValue(), nam.getNodeIP(), nam.getMeasurementIP(),
//                    nam.getSensorType()).save();
//        }
//    }

}
